import * as fs from 'fs/promises';
import * as path from 'path';

export class FileManager {
  private outputDir: string;
  private changelogPath: string;

  constructor() {
    // 使用绝对路径，确保在任何工作目录下都能正确找到输出目录
    // 检测是否在build目录中，如果是则向上两级，否则向上一级
    const currentDir = path.dirname(new URL(import.meta.url).pathname);
    const isBuildDir = currentDir.includes('/build') || currentDir.endsWith('/build');
    const projectRoot = isBuildDir 
      ? path.resolve(currentDir, '..') 
      : path.resolve(currentDir, '..');
    this.outputDir = path.join(projectRoot, 'drawio');
    this.changelogPath = path.join(this.outputDir, 'CHANGELOG.md');
  }

  async suggestFileName(moduleName: string, diagramType: string, version: string = 'v1.0'): Promise<any> {
    try {
      const timestamp = this.getCurrentDate();
      const fileName = `${moduleName}_${diagramType}_${version}_${timestamp}.drawio`;
      
      // 检查文件是否已存在
      const filePath = path.join(this.outputDir, fileName);
      let exists = false;
      
      try {
        await fs.access(filePath);
        exists = true;
      } catch {
        // 文件不存在，这是正常的
      }
      
      return {
        content: [
          {
            type: 'text',
            text: `# 文件命名建议\n\n## 建议的文件名\n\`${fileName}\`\n\n## 命名规则说明\n- **模块名**: ${moduleName}\n- **图表类型**: ${diagramType}\n- **版本号**: ${version}\n- **日期**: ${timestamp}\n\n## 文件状态\n${exists ? '⚠️ **警告**: 该文件名已存在，建议使用不同的版本号' : '✅ **可用**: 该文件名可以使用'}\n\n## 存储位置\n文件将保存到: \`${this.outputDir}/\`\n\n## 版本号规则\n- **v1.0**: 初始版本\n- **v1.1**: 小修改（组件调整、样式优化）\n- **v2.0**: 重大修改（架构更新、流程重构）`
          }
        ]
      };
    } catch (error) {
      return {
        content: [
          {
            type: 'text',
            text: `生成文件名建议失败: ${error instanceof Error ? error.message : String(error)}`
          }
        ]
      };
    }
  }

  async createVersionedFile(moduleName: string, diagramType: string, changeDescription?: string): Promise<any> {
    try {
      await this.ensureOutputDirectory();
      
      const timestamp = this.getCurrentDate();
      const version = await this.determineNextVersion(moduleName, diagramType, changeDescription);
      const fileName = `${moduleName}_${diagramType}_${version}_${timestamp}.drawio`;
      const filePath = path.join(this.outputDir, fileName);
      
      // 创建基础的Draw.io文件内容
      const drawioContent = this.createBasicDrawioTemplate(moduleName, diagramType);
      
      await fs.writeFile(filePath, drawioContent, 'utf-8');
      
      // 更新CHANGELOG
      await this.updateChangelog(fileName, version, changeDescription);
      
      return {
        content: [
          {
            type: 'text',
            text: `# 版本化文件创建成功\n\n## 创建的文件\n**文件名**: \`${fileName}\`\n**版本**: ${version}\n**位置**: \`${this.outputDir}/\`\n\n## 版本信息\n${changeDescription ? `**变更描述**: ${changeDescription}\n` : ''}**创建时间**: ${new Date().toLocaleString()}\n\n## 下一步操作\n1. 在Draw.io中打开文件进行编辑\n2. 根据需求添加图表内容\n3. 保存并提交更改\n\n## 版本管理\n- CHANGELOG已自动更新\n- 可以使用版本递增工具管理后续版本`
          }
        ]
      };
    } catch (error) {
      return {
        content: [
          {
            type: 'text',
            text: `创建版本化文件失败: ${error instanceof Error ? error.message : String(error)}`
          }
        ]
      };
    }
  }

  async suggestVersionIncrement(moduleName: string, diagramType: string, changeDescription: string): Promise<any> {
    try {
      const currentVersion = await this.findLatestVersion(moduleName, diagramType);
      const suggestedVersion = this.calculateNextVersion(currentVersion || 'v1.0', changeDescription);
      const changeType = this.analyzeChangeType(changeDescription);
      
      return {
        content: [
          {
            type: 'text',
            text: `# 版本递增建议\n\n## 当前版本\n${currentVersion || '未找到现有版本'}\n\n## 建议新版本\n**${suggestedVersion}**\n\n## 变更分析\n**变更类型**: ${changeType.type}\n**说明**: ${changeType.description}\n\n## 变更描述\n${changeDescription}\n\n## 版本递增规则\n- **补丁版本** (v1.0 → v1.1): 小修改、样式调整、错误修复\n- **次要版本** (v1.x → v2.0): 功能新增、架构调整\n- **主要版本** (vX.x → v(X+1).0): 重大重构、架构变更\n\n## 建议操作\n使用建议的版本号创建新文件，并在CHANGELOG中记录变更。`
          }
        ]
      };
    } catch (error) {
      return {
        content: [
          {
            type: 'text',
            text: `版本递增分析失败: ${error instanceof Error ? error.message : String(error)}`
          }
        ]
      };
    }
  }

  async cleanupTempFiles(): Promise<any> {
    try {
      await this.ensureOutputDirectory();
      
      const files = await fs.readdir(this.outputDir);
      const tempFiles = files.filter(file => 
        file.includes('_temp_') || 
        file.includes('_mermaid_') ||
        file.endsWith('.tmp') ||
        file.endsWith('.temp')
      );
      
      let deletedCount = 0;
      const deletedFiles: string[] = [];
      
      for (const file of tempFiles) {
        try {
          const filePath = path.join(this.outputDir, file);
          await fs.unlink(filePath);
          deletedFiles.push(file);
          deletedCount++;
        } catch (error) {
          console.error(`删除文件 ${file} 失败:`, error);
        }
      }
      
      return {
        content: [
          {
            type: 'text',
            text: `# 临时文件清理完成\n\n## 清理统计\n- **扫描目录**: \`${this.outputDir}/\`\n- **发现临时文件**: ${tempFiles.length} 个\n- **成功删除**: ${deletedCount} 个\n- **失败**: ${tempFiles.length - deletedCount} 个\n\n${deletedFiles.length > 0 ? `## 已删除的文件\n${deletedFiles.map(file => `- ${file}`).join('\n')}` : '## 结果\n没有找到需要清理的临时文件。'}\n\n## 建议\n建议定期执行此操作以保持目录整洁。临时文件包括：\n- 包含 \`_temp_\` 的文件\n- 包含 \`_mermaid_\` 的文件\n- \`.tmp\` 和 \`.temp\` 扩展名的文件`
          }
        ]
      };
    } catch (error) {
      return {
        content: [
          {
            type: 'text',
            text: `清理临时文件失败: ${error instanceof Error ? error.message : String(error)}`
          }
        ]
      };
    }
  }

  private async determineNextVersion(moduleName: string, diagramType: string, changeDescription?: string): Promise<string> {
    const currentVersion = await this.findLatestVersion(moduleName, diagramType);
    
    if (!currentVersion) {
      return 'v1.0';
    }
    
    if (changeDescription) {
      return this.calculateNextVersion(currentVersion, changeDescription);
    }
    
    return this.incrementPatchVersion(currentVersion);
  }

  private async findLatestVersion(moduleName: string, diagramType: string): Promise<string | null> {
    try {
      const files = await fs.readdir(this.outputDir);
      const pattern = new RegExp(`^${moduleName}_${diagramType}_v(\\d+)\\.(\\d+)_\\d{8}\\.drawio$`);
      
      let latestVersion = null;
      let maxMajor = 0;
      let maxMinor = 0;
      
      files.forEach(file => {
        const match = file.match(pattern);
        if (match) {
          const major = parseInt(match[1]);
          const minor = parseInt(match[2]);
          
          if (major > maxMajor || (major === maxMajor && minor > maxMinor)) {
            maxMajor = major;
            maxMinor = minor;
            latestVersion = `v${major}.${minor}`;
          }
        }
      });
      
      return latestVersion;
    } catch {
      return null;
    }
  }

  private calculateNextVersion(currentVersion: string, changeDescription: string): string {
    const changeType = this.analyzeChangeType(changeDescription);
    
    if (!currentVersion) {
      return 'v1.0';
    }
    
    const versionMatch = currentVersion.match(/v(\d+)\.(\d+)/);
    if (!versionMatch) {
      return 'v1.0';
    }
    
    const major = parseInt(versionMatch[1]);
    const minor = parseInt(versionMatch[2]);
    
    switch (changeType.level) {
      case 'major':
        return `v${major + 1}.0`;
      case 'minor':
        return `v${major}.${minor + 1}`;
      case 'patch':
      default:
        return `v${major}.${minor + 1}`;
    }
  }

  private analyzeChangeType(changeDescription: string): { type: string, description: string, level: string } {
    const description = changeDescription.toLowerCase();
    
    // 主要版本变更关键词
    const majorKeywords = ['重构', '架构', '重大', '完全', '重写', '迁移'];
    // 次要版本变更关键词
    const minorKeywords = ['新增', '添加', '功能', '模块', '组件'];
    // 补丁版本变更关键词
    const patchKeywords = ['修复', '调整', '优化', '样式', '布局', '颜色'];
    
    if (majorKeywords.some(keyword => description.includes(keyword))) {
      return {
        type: '重大变更',
        description: '涉及架构重构或重大功能变更',
        level: 'major'
      };
    }
    
    if (minorKeywords.some(keyword => description.includes(keyword))) {
      return {
        type: '功能变更',
        description: '新增功能或模块',
        level: 'minor'
      };
    }
    
    if (patchKeywords.some(keyword => description.includes(keyword))) {
      return {
        type: '小修改',
        description: '样式调整、错误修复或小优化',
        level: 'patch'
      };
    }
    
    return {
      type: '常规变更',
      description: '常规修改，建议小版本递增',
      level: 'patch'
    };
  }

  private incrementPatchVersion(version: string): string {
    const match = version.match(/v(\d+)\.(\d+)/);
    if (match) {
      const major = parseInt(match[1]);
      const minor = parseInt(match[2]);
      return `v${major}.${minor + 1}`;
    }
    return 'v1.1';
  }

  private createBasicDrawioTemplate(moduleName: string, diagramType: string): string {
    const title = `${moduleName} ${diagramType}`;
    
    return `<?xml version="1.0" encoding="UTF-8"?>
<mxfile host="app.diagrams.net" modified="${new Date().toISOString()}" agent="DrawIO-MCP" etag="generated" version="22.1.16" type="device">
  <diagram name="Page-1" id="page1">
    <mxGraphModel dx="1422" dy="794" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
      <root>
        <mxCell id="0" />
        <mxCell id="1" parent="0" />
        <mxCell id="2" value="${title}" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=16;fontStyle=1;" vertex="1" parent="1">
          <mxGeometry x="300" y="50" width="200" height="30" as="geometry" />
        </mxCell>
        <mxCell id="3" value="请在此处开始创建您的${diagramType}图表" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
          <mxGeometry x="250" y="150" width="300" height="60" as="geometry" />
        </mxCell>
      </root>
    </mxGraphModel>
  </diagram>
</mxfile>`;
  }

  private async updateChangelog(fileName: string, version: string, changeDescription?: string): Promise<void> {
    try {
      const timestamp = new Date().toLocaleDateString();
      const entry = `## [${version}] - ${timestamp}\n\n### 新增（Added）\n- **${fileName}**: ${changeDescription || '创建新的图表文件'}\n\n### 技术细节\n- 使用MCP工具自动生成\n- 符合项目规范要求\n\n---\n\n`;
      
      let existingContent = '';
      try {
        existingContent = await fs.readFile(this.changelogPath, 'utf-8');
      } catch {
        // CHANGELOG不存在，创建新的
        existingContent = '# 变更日志\n\n本文件记录项目中所有Draw.io图表文件的变更历史。\n\n---\n\n';
      }
      
      const newContent = existingContent.replace('---\n\n', entry);
      await fs.writeFile(this.changelogPath, newContent, 'utf-8');
    } catch (error) {
      console.error('更新CHANGELOG失败:', error);
    }
  }

  private async ensureOutputDirectory(): Promise<void> {
    try {
      await fs.access(this.outputDir);
    } catch {
      await fs.mkdir(this.outputDir, { recursive: true });
    }
  }

  private getCurrentDate(): string {
    const now = new Date();
    const year = now.getFullYear();
    const month = String(now.getMonth() + 1).padStart(2, '0');
    const day = String(now.getDate()).padStart(2, '0');
    return `${year}${month}${day}`;
  }
}
